
package com.jf.cloud.discount.controller.app;

import cn.hutool.core.collection.CollectionUtil;
import com.jf.cloud.api.discount.constant.DiscountRule;
import com.jf.cloud.api.dto.EsPageDTO;
import com.jf.cloud.api.feign.SearchSpuFeignClient;
import com.jf.cloud.api.vo.EsPageVO;
import com.jf.cloud.common.database.dto.PageDTO;
import com.jf.cloud.common.database.vo.PageVO;
import com.jf.cloud.common.exception.LuckException;
import com.jf.cloud.common.product.dto.ProductSearchDTO;
import com.jf.cloud.common.product.vo.search.ProductSearchVO;
import com.jf.cloud.common.product.vo.search.SpuSearchVO;
import com.jf.cloud.common.response.ResponseEnum;
import com.jf.cloud.common.response.ServerResponseEntity;
import com.jf.cloud.common.util.Arith;
import com.jf.cloud.discount.constant.SuitableProdTypeEnum;
import com.jf.cloud.discount.mapper.DiscountSpuMapper;
import com.jf.cloud.discount.model.Discount;
import com.jf.cloud.discount.model.DiscountSpu;
import com.jf.cloud.discount.service.DiscountService;
import com.jf.cloud.discount.vo.DiscountItemVO;
import com.jf.cloud.discount.vo.DiscountVO;
import io.swagger.v3.oas.annotations.tags.Tag;
import io.swagger.v3.oas.annotations.Parameter;
import io.swagger.v3.oas.annotations.Operation;
import org.springdoc.api.annotations.ParameterObject;
import org.springframework.beans.factory.annotation.Autowired;
import org.springframework.web.bind.annotation.GetMapping;
import org.springframework.web.bind.annotation.RequestMapping;
import org.springframework.web.bind.annotation.RequestParam;
import org.springframework.web.bind.annotation.RestController;

import java.util.*;
import java.util.stream.Collectors;

/**
 * 满减满折优惠
 *
 * @author zz
 * @date 2020-12-10 13:43:38
 */
@RestController("appDiscountController")
@RequestMapping("/ua/discount")
@Tag(name = "满减满折优惠")
public class DiscountController {

    @Autowired
    private DiscountService discountService;

    @Autowired
    private DiscountSpuMapper discountSpuMapper;

    @Autowired
    private SearchSpuFeignClient searchSpuFeignClient;

    @GetMapping("/list")
    @Operation(summary = "获取促销活动列表" , description = "获取促销活动列表")
    public ServerResponseEntity<PageVO<DiscountVO>> getDiscountList(PageDTO page,@ParameterObject Discount discount) {
        PageVO<DiscountVO> spuPage = discountService.getAppDiscountList(page);
        return ServerResponseEntity.success(spuPage);
    }

    @GetMapping("/info")
    @Operation(summary = "获取满减活动信息" , description = "获取满减活动信息")
    @Parameter(name = "discountId", description = "活动ID" , required = true)
    public ServerResponseEntity<DiscountVO> info(@RequestParam("discountId") Long discountId) {
        DiscountVO discount = discountService.discountInfo(discountId);
        if (Objects.isNull(discount)){
            // 该活动不存在或者已结束
            return ServerResponseEntity.showFailMsg("该活动不存在或者已结束");
        }
        discount.setSpuIds(null);
        return ServerResponseEntity.success(discount);
    }

    @GetMapping("/spu_page_by_discount_id")
    @Operation(summary = "获取促销活动商品分页" , description = "通过活动id获取促销活动详情")
    @Parameter(name = "discountId", description = "活动ID" , required = true)
    public ServerResponseEntity<EsPageVO<ProductSearchVO>> getSpuPageByDiscountId(EsPageDTO pageDTO,@ParameterObject ProductSearchDTO productSearchDTO,
                                                                    @RequestParam("discountId") Long discountId) {
        DiscountVO discount = discountService.getDiscountInfoById(discountId);
        if(!Objects.equals(discount.getStatus(),1)){
            return ServerResponseEntity.success(null);
        }
        if (Objects.equals(discount.getSuitableSpuType(), SuitableProdTypeEnum.ALL_SPU.value())) {
            productSearchDTO.setShopId(discount.getShopId());
        } else {
            productSearchDTO.setSpuIds(discount.getSpuIds());
        }
        productSearchDTO.setPageNum(pageDTO.getPageNum());
        productSearchDTO.setPageSize(pageDTO.getPageSize());
        ServerResponseEntity<EsPageVO<ProductSearchVO>> response = searchSpuFeignClient.search(productSearchDTO);
        if (Objects.nonNull(response) && !Objects.equals(response.getCode(), ResponseEnum.OK.value())) {
            throw new LuckException(response.getMsg());
        }
        List<SpuSearchVO> spuList = response.getData().getList().get(0).getSpus();
        if (CollectionUtil.isNotEmpty(spuList)) {

            // 最优惠的那个满减项
            DiscountItemVO discountItem = discount.getDiscountItemList().get(0);

            // 折扣百分比
            double discountProportion;

            // 打折
            if (Objects.equals(discount.getDiscountRule(), DiscountRule.P2D.value())) {
                discountProportion = Arith.sub(1,Arith.div(discountItem.getDiscount(), 1000));
            } else {
                discountProportion = Arith.div(discountItem.getDiscount(), discountItem.getNeedAmount());
            }
            for (SpuSearchVO spuSearchVO : spuList) {
                // 将要减去的价格
                Double subPriceDouble = Arith.div(Arith.mul(spuSearchVO.getPriceFee(), discountProportion),1.0,0);
                Long subPrice = subPriceDouble.longValue();
                // 如果有活动价格上限
                if (discount.getMaxReduceAmount() != null && subPrice > discount.getMaxReduceAmount()) {
                    subPrice = discount.getMaxReduceAmount();
                }
                //价格最低只能为0.01
                long activityPrice = spuSearchVO.getPriceFee() - subPrice;
                if (activityPrice < 1L){
                    activityPrice = 1L;
                }
                spuSearchVO.setActivityPrice(activityPrice);
            }
            if(Objects.equals(discount.getSuitableSpuType(), SuitableProdTypeEnum.ASSIGN_SPU.value()) && Objects.isNull(productSearchDTO.getSort())){
                //根据满减商品id排序
                Map<Long, SpuSearchVO> searchMap = spuList.stream().collect(Collectors.toMap(SpuSearchVO::getSpuId, s -> s));
                List<DiscountSpu> discountSpuList = discountSpuMapper.getDiscountSpuByDiscountId(discountId);
                discountSpuList = discountSpuList.stream().sorted(Comparator.comparing(DiscountSpu::getDiscountSpuId)).collect(Collectors.toList());
                LinkedHashMap<Long , Long> discountSpuMap = new LinkedHashMap<>();
                discountSpuList.forEach(s-> discountSpuMap.put(s.getDiscountSpuId(), s.getSpuId()));
                List<SpuSearchVO> spuVOList = new ArrayList<>();
                for(Map.Entry<Long, Long> entry : discountSpuMap.entrySet()){
                    if(searchMap.containsKey(entry.getValue())){
                        spuVOList.add(searchMap.get(entry.getValue()));
                    }
                }
                spuList = spuVOList;
                response.getData().getList().get(0).setSpus(spuList);
            }
        }
        return ServerResponseEntity.success(response.getData());
    }
}
